﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;

using System.IO;
using TSharp.Core.Util.Security;
using TSharp.Core.Env;
using TSharp.Core.Util.TypeConvert;
using TSharp.Core.Util.Numeric;


namespace TSharp.Core.RsaUtil
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            selectFile.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            ReadFile(txtFilePath.Text.Trim(), txtPwd.Text.Trim());
        }
        void ReadFile(string file, string pwd)
        {
            if (File.Exists(file))
            {
                try
                {
                    var rsautil = new RSAUtil();
                    if (Path.GetExtension(file).Equals(".snk", StringComparison.CurrentCultureIgnoreCase))
                        rsautil.LoadKeyFromCerFile(file);
                    else
                        rsautil.LoadKeyFromPfxFile(file, pwd);

                    txtPrivateKey.Text = rsautil.XmlPrivateKey;
                    txtPublicKey.Text = rsautil.XmlPublicKey;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            else
            {
                MessageBox.Show("文件不存在！");
            }

        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            selectFile.ShowDialog(this);
        }

        private void selectFile_FileOk(object sender, CancelEventArgs e)
        {
            this.txtFilePath.Text = selectFile.FileName;
        }

        private void btnBuildSerialNo_Click(object sender, EventArgs e)
        {
            var util = new RSAUtil().UseDefaultPrivateKeyFile();

            var mac = Computer.MacAddress;

            var sign = util.SignData(Encoding.UTF8.GetBytes(mac));
            BigInteger v = new BigInteger(sign);
            this.txtPublicKey.Text = v.ToString(16);
        }

        private void btnVerifySerialNo_Click(object sender, EventArgs e)
        {
            var util = new RSAUtil().UseDefaultPublicKeyFile();

            var mac = Computer.MacAddress;

            var verify = util.VerifyData(Encoding.UTF8.GetBytes(mac), new BigInteger(this.txtPublicKey.Text,16).getBytes());

            this.txtPrivateKey.Text = verify.ToString();
        }


        /// <summary>
        /// 对原始数据进行MD5加密
        /// </summary>
        /// <param name="key">待加密的注册码</param>
        /// <returns>加密后的注册码</returns>
        public static string GetMD5(string key)
        {
            HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(key);
            byte[] inArray = algorithm.ComputeHash(bytes);
            string strEncrypt = Convert.ToBase64String(inArray);
            return strEncrypt;

        }

        /// <summary>
        /// 使用私钥加密客户注册码[注册码+GUID码]
        /// </summary>
        /// <param name="key">客户注册码[注册码+GUID码]</param>
        /// <param name="keyContainerName">密钥容器名称</param>
        /// <param name="keyPath">私钥文件地址</param>
        /// <returns>加密后的注册码</returns>
        public static string EncryptKey(string key, string keyContainerName, string keyPath)
        {
            CspParameters cspParameter = new CspParameters();
            StreamReader sr = new StreamReader(keyPath);
            cspParameter.KeyContainerName = keyContainerName;
            string strKey = sr.ReadLine();
            string strEncrypt = string.Empty;
            byte[] byteKeys = Convert.FromBase64String(GetMD5(key));

            RSACryptoServiceProvider provider = new RSACryptoServiceProvider(cspParameter);
            provider.FromXmlString(strKey);
            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(provider);
            formatter.SetHashAlgorithm("MD5");
            byte[] byteEncrypt = formatter.CreateSignature(byteKeys);
            strEncrypt = Convert.ToBase64String(byteEncrypt);
            return strEncrypt;
        }

        /// <summary>
        /// 使用公钥解密客户注册码验证
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="key">授权文件信息</param>
        /// <param name="computeInfo">电脑硬件信息</param>
        public static bool Decrypt(string publicKey, string key, string computeInfo)
        {
            try
            {
                CspParameters cspParameter = new CspParameters();
                cspParameter.KeyContainerName = "public";
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider(cspParameter);
                provider.FromXmlString(publicKey);
                RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(provider);
                deformatter.SetHashAlgorithm("MD5");

                //转换授权文件信息字符串
                byte[] byteAuthorization = Convert.FromBase64String(key);
                //转换当前电脑硬件信息
                byte[] byteComputeInfo = Convert.FromBase64String(GetMD5(computeInfo));
                if (deformatter.VerifySignature(byteAuthorization, byteComputeInfo))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                //WriteSystemLog(5, 3, "000000", ex.Message);
                throw new Exception(ex.Message, ex);
            }
        }
    }
}
